home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 24 / AACD 24.iso / AACD / System / ReqToolsLib / Source / reqtools / filereq.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-07-02  |  25.8 KB  |  984 lines

  1. /**f************************************************************
  2. *                                                             *
  3. *      File/Font/Screenmode requester                         *
  4. *                                                             *
  5. *                                 (c) Nico François 1991-1994 *
  6. **************************************************************/
  7.  
  8. #include <proto/wb.h>
  9.  
  10. #include "filereq.h"
  11.  
  12. /****************************************************************************************/
  13.  
  14. struct Library        *WorkbenchBase;
  15.  
  16. char TOPAZSTR[] = "topaz.font";
  17. char DOTINFOSTR[] = ".info";
  18.  
  19. struct TextAttr topaz80 = { "topaz.font",8,FS_NORMAL,FPF_ROMFONT|FPF_DESIGNED };
  20.  
  21.  
  22. /****************************************************************************************/
  23.  
  24. #define FILEREQ_FLAGS \
  25.     (FREQF_NOBUFFER|FREQF_DOWILDFUNC|FREQF_MULTISELECT|FREQF_SAVE|FREQF_NOFILES|\
  26.      FREQF_PATGAD|FREQF_SELECTDIRS)
  27. #define FONTREQ_FLAGS \
  28.     (FREQF_NOBUFFER|FREQF_DOWILDFUNC|FREQF_FIXEDWIDTH|FREQF_COLORFONTS|\
  29.      FREQF_CHANGEPALETTE|FREQF_LEAVEPALETTE|FREQF_SCALE|FREQF_STYLE)
  30. #define SCREENMODEREQ_FLAGS \
  31.     (SCREQF_SIZEGADS|SCREQF_DEPTHGAD|SCREQF_NONSTDMODES|SCREQF_GUIMODES|\
  32.      SCREQF_AUTOSCROLLGAD|SCREQF_OVERSCANGAD)
  33.  
  34. /****************************************************************************************/
  35.  
  36. /********************
  37. *                   *
  38. *  REQUESTER ENTRY  *
  39. *                   *
  40. ********************/
  41.  
  42. /* This is also FontRequestA and ScreenModeRequestA! */
  43.  
  44. APTR ASM SAVEDS FileRequestA (
  45.     REGPARAM(a1, struct RealFileRequester *, freq),
  46.     REGPARAM(a2, char *, filename),
  47.     REGPARAM(a3, char *, title),
  48.     REGPARAM(a0, struct TagItem *, taglist))
  49. {
  50.     GlobData                 *glob;
  51.     struct ReqEntry             *entry;
  52.     struct TagItem            *tag, *tstate;
  53.     struct RealFontRequester         *fontreq;
  54.     struct RealScreenModeRequester     *scrmodereq;
  55.     struct DiskfontBase         *DiskfontBase;
  56.     struct TextAttr             *fontattr = NULL;
  57.     struct TextFont             *deffont;
  58.     struct Locale             *locale = NULL;
  59.     char                 *pubname = NULL;
  60.     int                 reqhandler = FALSE, mon, propmaskset = FALSE;
  61.     ULONG                 tagdata;
  62.  
  63.  
  64.     if (!(glob = AllocVec (sizeof(GlobData), MEMF_PUBLIC|MEMF_CLEAR)))
  65.      return ((APTR)FALSE);
  66.  
  67.     glob->reqtype = REQTYPE(freq);
  68.     if (glob->reqtype == RT_FILEREQ)
  69.     {
  70.  
  71.     /* AROS timer.device checks IO length to make sure apps
  72.        dont use a too small/wrong iorequest structure */
  73.        
  74.     glob->timereq.tr_node.io_Message.mn_Length = sizeof(glob->timereq);
  75.     
  76.     if (OpenDevice ("timer.device", UNIT_VBLANK, (struct IORequest *)&glob->timereq, 0))
  77.     {
  78.  
  79.         FreeVec (glob);
  80.         return ((APTR)FALSE);
  81.     }
  82.     
  83.     glob->buff = &freq->buff;
  84.     glob->freq = freq;
  85.     freq->filename = filename;
  86.     glob->wilddotinfo = EndsInDotInfo (freq->patstr, strlen (freq->patstr));
  87.     ParsePatternNoCase (freq->patstr, glob->matchpat, sizeof( glob->matchpat ) );
  88.     }
  89.     else if (glob->reqtype == RT_FONTREQ)
  90.     {
  91.  
  92.     DiskfontBase = (struct DiskfontBase *)OldOpenLibrary ("diskfont.library");
  93.     glob->diskfontbase = DiskfontBase;
  94.     
  95.     if (!DiskfontBase)
  96.     {
  97.         FreeAll (glob);
  98.         return ((APTR)FALSE);
  99.     }
  100.     
  101.     glob->fontreq = fontreq = (struct RealFontRequester *)freq;
  102.     glob->buff = &fontreq->buff;
  103.     filename = fontreq->fontname;
  104.     glob->sampleheight = 24;
  105.     glob->maxsize = MAXINT;
  106.     }
  107.     else
  108.     { /* RT_SCREENMODEREQ */
  109.  
  110.     glob->scrmodereq = scrmodereq = (struct RealScreenModeRequester *)freq;
  111.     glob->buff = &scrmodereq->buff;
  112.     }
  113.     
  114.     /* defaults */
  115.     glob->flags = freq->Flags;                /* = [scmd|font]req->Flags */
  116.     glob->reqpos = freq->ReqPos;           /* = [scmd|font]req->ReqPos */
  117.     glob->leftedge = freq->LeftOffset;     /* = [scmd|font]req->LeftOffset */
  118.     glob->topedge = freq->TopOffset;       /* = [scmd|font]req->TopOffset */
  119.     deffont = freq->DefaultFont;           /* = [scmd|font]req->DefaultFont */
  120.     glob->waitpointer = freq->WaitPointer; /* = [scmd|font]req->WaitPointer */
  121.     glob->lockwindow = freq->LockWindow;    /* = [scmd|font]req->LockWindow */
  122.     glob->shareidcmp = freq->ShareIDCMP;     /* = [scmd|font]req->ShareIDCMP */
  123.     glob->reqheight = freq->ReqHeight;        /* = [scmd|font]req->ReqHeight */
  124.  
  125.     /* These must be (but automatically are, MEMF_CLEAR) NULL */
  126. //    glob->gadtxt[4] = NULL;
  127. // glob->underchar = 0;
  128.  
  129.     /* init global vars */
  130.     glob->firstentry = glob->buff->firstname;
  131.     glob->bufferentry = (glob->firstentry != NULL);
  132.     glob->req = freq;
  133.     glob->newdir = TRUE;
  134.     glob->maxdepth = glob->maxwidth = glob->maxheight = MAXINT;
  135.  
  136.  
  137.  
  138.     /* parse tags */
  139.     tstate = taglist;
  140.     while ((tag = NextTagItem ((const struct TagItem **)&tstate)))
  141.     {
  142.     tagdata = tag->ti_Data;
  143.     if (tag->ti_Tag > RT_TagBase)
  144.     {
  145.         switch (tag->ti_Tag)
  146.         {
  147.         case RT_Window:        glob->prwin = (struct Window *)tagdata;
  148.                     break;
  149.         case RT_ReqPos:        glob->reqpos = tagdata; break;
  150.         case RT_LeftOffset:    glob->leftedge = tagdata; break;
  151.         case RT_TopOffset:    glob->topedge = tagdata; break;
  152.         case RT_PubScrName:    pubname = (char *)tagdata; break;
  153.         case RT_Screen:        glob->scr = (struct Screen *)tagdata; break;
  154.         case RT_ReqHandler:    *(APTR *)tagdata = glob;
  155.                     reqhandler = TRUE;
  156.                     break;
  157.         case RT_DefaultFont:    deffont = (struct TextFont *)tagdata; break;
  158.         case RT_WaitPointer:     glob->waitpointer = tagdata; break;
  159.         case RT_Underscore:    glob->underchar = tagdata; break;
  160.         case RT_ShareIDCMP:    glob->shareidcmp = tagdata; break;
  161.         case RT_LockWindow:    glob->lockwindow = tagdata; break;
  162.         case RT_ScreenToFront:     glob->noscreenpop = !tagdata; break;
  163.         case RT_TextAttr:        fontattr = (struct TextAttr *)tagdata; break;
  164.         case RT_IntuiMsgFunc:     glob->imsghook = (struct Hook *)tagdata; break;
  165.         case RT_Locale:        locale = (struct Locale *)tagdata; break;
  166.         /* RTFO_Flags, RTSC_Flags */
  167.         case RTFI_Flags:    if (glob->reqtype == RT_FILEREQ)
  168.                         tagdata &= FILEREQ_FLAGS;
  169.                     else if (glob->reqtype == RT_FONTREQ)
  170.                         tagdata &= FONTREQ_FLAGS;
  171.                     else
  172.                     {
  173.                         tagdata &= SCREENMODEREQ_FLAGS;
  174.                         tagdata |= FREQF_NOBUFFER;
  175.                     }
  176.                     glob->flags = tagdata;
  177.                     break;
  178.         /* RTFO_Height, RTSC_Height */
  179.         case RTFI_Height:    glob->reqheight = tagdata;
  180.                     break;
  181.         /* RTFO_OkText, RTSC_OkText */
  182.         case RTFI_OkText:    glob->gadtxt[4] = (char *)tagdata; break;
  183.         case RTFI_VolumeRequest: glob->volumerequest = 0x80000000 | tagdata; break;
  184.         /* RTFO_FilterFunc, RTSC_FilterFunc */
  185.         case RTFI_FilterFunc:     glob->filterhook = (struct Hook *)tagdata; break;
  186.         case RTFI_AllowEmpty:     glob->allowempty = tagdata; break;
  187.         case RTFO_SampleHeight: glob->sampleheight = tagdata; break;
  188.         case RTFO_MinHeight:    glob->minsize = tagdata; break;
  189.         case RTFO_MaxHeight:    glob->maxsize = tagdata; break;
  190.         case RTSC_PropertyFlags: glob->propertyflags = tagdata;
  191.                      if (!propmaskset) glob->propertymask = 0xFFFFFFFF;
  192.                      break;
  193.         case RTSC_PropertyMask: glob->propertymask = tagdata;
  194.                     propmaskset = TRUE;
  195.                     break;
  196.         case RTSC_MinWidth:    glob->minwidth = tagdata; break;
  197.         case RTSC_MaxWidth:    glob->maxwidth = tagdata; break;
  198.         case RTSC_MinHeight:    glob->minheight = tagdata; break;
  199.         case RTSC_MaxHeight:    glob->maxheight = tagdata; break;
  200.         case RTSC_MinDepth:    glob->mindepth = tagdata; break;
  201.         case RTSC_MaxDepth:    glob->maxdepth = tagdata; break;
  202.  
  203.         }
  204.     }
  205.     }
  206.  
  207.  
  208.  
  209.     glob->catalog = RT_OpenCatalog (locale);
  210.     if (!glob->gadtxt[4])
  211.     {
  212.     glob->gadtxt[4] = GetStr (glob->catalog, MSG_OK);
  213.     glob->underchar = '_';
  214.     }
  215.  
  216.  
  217.     if (glob->volumerequest)
  218.     {
  219.     FreeReqBuffer (glob->req);
  220.     glob->flags |= FREQF_NOFILES|FREQF_NOBUFFER;
  221.     glob->flags &= ~(FREQF_SAVE|FREQF_PATGAD|FREQF_SELECTDIRS);
  222.     }
  223.  
  224.  
  225.     if (glob->reqtype == RT_FILEREQ)
  226.     {
  227.     if (glob->flags & FREQF_NOFILES)
  228.         SetFileDirMode (glob->buff, glob->flags);
  229.     glob->file_id = glob->buff->file_id;
  230.     glob->directory_id = glob->buff->directory_id;
  231.     }
  232.  
  233.  
  234.     if (!glob->prwin || !glob->prwin->UserPort
  235.              || (glob->prwin->UserPort->mp_SigTask != ThisProcess()))
  236.     glob->shareidcmp = FALSE;
  237.  
  238.  
  239.     if (!(glob->scr = GetReqScreen (&glob->newreqwin, &glob->prwin,
  240.                               glob->scr, pubname)))
  241.     {
  242.     FreeAll (glob);
  243.     return ((APTR)FALSE);
  244.     }
  245.  
  246.     
  247.     glob->vp = &glob->scr->ViewPort;
  248.     if (glob->flags & FREQF_CHANGEPALETTE)
  249.     {
  250.     if (!(glob->colcount = GetVpCM (glob->vp, &glob->colormap)))
  251.     {
  252.         FreeAll (glob);
  253.         return ((APTR)FALSE);
  254.     }
  255.     glob->colcount = (1 << glob->colcount);
  256.     }
  257.  
  258.     
  259.     if (fontattr) glob->font = *fontattr;
  260.     else glob->font = *glob->scr->Font;
  261.  
  262.     if (glob->reqtype == RT_SCREENMODEREQ)
  263.     {
  264.  
  265.     if (scrmodereq->DisplayID == INVALID_ID)
  266.     {
  267.         glob->modeid = GetVPModeID (glob->vp);
  268.         glob->depth = glob->scr->BitMap.Depth;
  269.         glob->width = glob->scr->Width;
  270.         glob->height = glob->scr->Height;
  271.         glob->autoscroll = (glob->scr->Flags & AUTOSCROLL);
  272.     }
  273.     else
  274.     {
  275.         glob->modeid = scrmodereq->DisplayID;
  276.         glob->depth = scrmodereq->DisplayDepth;
  277.         glob->width = scrmodereq->DisplayWidth;
  278.         glob->height = scrmodereq->DisplayHeight;
  279.         glob->autoscroll = scrmodereq->AutoScroll;
  280.     }
  281.     
  282.     glob->overscantype = scrmodereq->OverscanType;
  283.     if (!GetModeData (glob, glob->modeid, &mon))
  284.         glob->modeid = INVALID_ID;
  285.     else
  286.     {
  287.         GetModeDimensions (glob);
  288.         if (glob->width == 0xffff) glob->width = glob->defwidth;
  289.         if (glob->height == 0xffff) glob->height = glob->defheight;
  290.         if (glob->depth == 0xffff) glob->depth = glob->diminfo.MaxDepth;
  291.         if (!(glob->flags & SCREQF_SIZEGADS))
  292.         glob->usedefwidth = glob->usedefheight = TRUE;
  293.         else
  294.         {
  295.         glob->usedefwidth = (glob->width == glob->defwidth);
  296.         glob->usedefheight = (glob->height == glob->defheight);
  297.         }
  298.     }
  299.     }
  300.  
  301.  
  302.     if (!(glob->visinfo = GetVisualInfoA (glob->scr, NULL))
  303.     || !(glob->drinfo = GetScreenDrawInfo (glob->scr)))
  304.     {
  305.     FreeAll (glob);
  306.     return ((APTR)FALSE);
  307.     }
  308.  
  309.  
  310.     glob->pens = glob->drinfo->dri_Pens;
  311.     glob->title = title;
  312.     glob->os30 = (IntuitionBase->LibNode.lib_Version >= 39);
  313.  
  314.     if (!glob->buff->firstname)
  315.     {
  316.     glob->buff->gotopos = glob->buff->pos = glob->buff->currentnum = 0;
  317.     }
  318.  
  319.  
  320.     entry = glob->buff->firstname;
  321.     while (entry)
  322.     {
  323.     entry->re_EntryLen = entry->re_SizeLenPix = 0;
  324.     entry = (struct ReqEntry *)entry->re_Next;
  325.     }
  326.  
  327.  
  328. retryopenwin:
  329.  
  330.     if (!(glob->reqfont = GetReqFont (&glob->font, deffont, &glob->fontheight,
  331.                       &glob->fontwidth, TRUE)))
  332.     {
  333.     FreeAll (glob);
  334.     return ((APTR)FALSE);
  335.     }
  336.     glob->fontbase = glob->reqfont->tf_Baseline;
  337.  
  338.  
  339.     if (!SetupReqWindow (glob, FALSE))
  340.     {
  341.  
  342.     if (glob->font.ta_YSize > 8)
  343.     {
  344.         glob->font = topaz80;
  345.         CloseFont (glob->reqfont);
  346.         goto retryopenwin;
  347.     }
  348.     FreeAll (glob);
  349.     return ((APTR)FALSE);
  350.     }
  351.  
  352.  
  353.     if (glob->reqtype == RT_SCREENMODEREQ) DisplayModeAttrs (glob);
  354.     RenderReqWindow (glob, FALSE, TRUE);
  355.     glob->winlock = DoLockWindow (glob->prwin, glob->lockwindow, NULL, TRUE);
  356.     DoWaitPointer (glob->prwin, glob->waitpointer, TRUE);
  357.  
  358.     /* initialize hook structure */
  359.     glob->intuihook.h_Entry = (ULONG (*)())IntuiMsgFunc;
  360.     glob->intuihook.h_Data = (void *)glob;
  361.  
  362.     glob->frontscr = IntuitionBase->FirstScreen;
  363.     DoScreenToFront (glob->scr, glob->noscreenpop, TRUE);
  364.  
  365.     my_SetStringGadget (glob->reqwin, glob->filegad, filename);
  366.  
  367.     /* fill in RealHandlerInfo */
  368.     glob->func = (ULONG (*)())PropReqHandler;
  369.     glob->WaitMask = glob->winmask = (1 << glob->reqwin->UserPort->mp_SigBit);
  370.     if (glob->appwindow) glob->WaitMask |= (1 << glob->appwinport->mp_SigBit);
  371.     glob->DoNotWait = TRUE;
  372.  
  373.     if (reqhandler) return ((APTR)CALL_HANDLER);
  374.     return ((APTR)LoopReqHandler ((struct rtHandlerInfo *)glob));
  375. }
  376.  
  377. /****************************************************************************************/
  378.  
  379. /**************
  380. *             *
  381. *  MAIN LOOP  *
  382. *             *
  383. ***************/
  384.  
  385. void STDARGS SAVEDS FreeReqToolsFonts (void)
  386. {
  387.     struct AssignList *list, *next;
  388.  
  389.     FreeVec (ReqToolsBase->AvailFontsHeader);
  390.     list = ReqToolsBase->FontsAssignList;
  391.     while (list)
  392.     {
  393.     next = list->al_Next;
  394.     FreeVec (list);
  395.     list = next;
  396.     }
  397.     ReqToolsBase->AvailFontsHeader = NULL;
  398.     ReqToolsBase->FontsAssignList = NULL;
  399. }
  400.  
  401. /****************************************************************************************/
  402.  
  403. int REGARGS CalcClicked (GlobData *glob, struct IntuiMessage *im)
  404. {
  405.     return ((im->MouseY - glob->boxtop) / glob->entryheight);
  406. }
  407.  
  408. /****************************************************************************************/
  409.  
  410. void REGARGS CompClicked (GlobData *glob)
  411. {
  412.     glob->displaylist[glob->clicked]->re_Flags ^= ENTRYF_SELECTED|ENTRYF_HIGHLIGHTED;
  413.     PrintEntry (glob, glob->clicked);
  414. }
  415.  
  416. /****************************************************************************************/
  417.  
  418. /* TIMER STUFF */
  419.  
  420. void REGARGS StopTimer (GlobData *glob)
  421. {
  422.     struct Node *node;
  423.     int     othermsgs = FALSE, gotreply = FALSE;
  424.  
  425.    if (glob->timerstarted)
  426.     {
  427.     AbortIO ((struct IORequest *)&glob->timereq);
  428.     /* We don't use WaitIO() since not sure it leaves other messages
  429.         intact. */
  430.     while (!gotreply)
  431.     {
  432.         Wait (glob->winmask);
  433.         /* Traverse message list and look for timereq msg */
  434.         Disable();
  435.         for (node = glob->reqwin->UserPort->mp_MsgList.lh_Head;
  436.          node->ln_Succ; node = node->ln_Succ)
  437.         {
  438.         if (node == (struct Node *)&glob->timereq)
  439.         {
  440.             Remove (node);
  441.             gotreply = TRUE;
  442.             break;
  443.         }
  444.         else othermsgs = TRUE;
  445.         }
  446.         Enable();
  447.     }
  448.     
  449.     if (othermsgs) Signal ((struct Task *)ThisProcess(), glob->winmask);
  450.     glob->timerstarted = FALSE;
  451.     }
  452.  
  453. }
  454.  
  455. /****************************************************************************************/
  456.  
  457. void REGARGS StartTimer (GlobData *glob, int micros)
  458. {
  459.     StopTimer (glob);
  460.     
  461.     glob->timereq.tr_node.io_Command = TR_ADDREQUEST;
  462.     glob->timereq.tr_time.tv_secs = 0;
  463.     glob->timereq.tr_time.tv_micro = micros;
  464.     SendIO ((struct IORequest *)&glob->timereq);
  465.     
  466.     glob->timerstarted = TRUE;
  467. }
  468.  
  469. /****************************************************************************************/
  470.  
  471. void REGARGS EndQuiet (GlobData *glob)
  472. {
  473.     int i;
  474.  
  475.     if (glob->quiet)
  476.     {
  477.     if (!glob->exnext)
  478.     {
  479.         if (rtLockPrefs()->Flags & RTPRF_IMMSORT) glob->firsttimer = TRUE;
  480.         rtUnlockPrefs();
  481.     }
  482.     
  483.     if (glob->firsttimer)
  484.     {
  485.         ScrollerMoved (glob, glob->buff->gotopos);
  486.         glob->firsttimer = FALSE;
  487.     }
  488.     else
  489.     {
  490.         if (glob->lastdisplaylistnum != -1)
  491.         {
  492.         if (glob->lastdisplaylistnum < glob->numentries)
  493.         {
  494.             i = glob->lastdisplaylistnum;
  495.             glob->lastdisplaylistnum = -1;
  496.             while (i < glob->numentries) PrintEntry (glob, i++);
  497.         }
  498.         }
  499.         AdjustScroller (glob);
  500.     }
  501.     }
  502.     
  503.     if (glob->exnext) StartTimer (glob, 200000);
  504.     else
  505.     {
  506.     StopTimer (glob);
  507.     glob->quiet = FALSE;
  508.     }
  509. }
  510.  
  511. /****************************************************************************************/
  512.  
  513. /* MAIN LOOP */
  514.  
  515. struct IntuiMessage *REGARGS ProcessWin_Msg_Freq (GlobData *glob, struct IntuiMessage *imsg)
  516. {
  517.     struct IntuiMessage *reqmsg;
  518.  
  519.     if (imsg->IDCMPWindow == glob->reqwin)
  520.     {
  521.     reqmsg = GT_FilterIMsg (imsg);
  522.     if (reqmsg) return (reqmsg);
  523.     ReplyMsg ((struct Message *)imsg);
  524.     }
  525.     else
  526.     {
  527.     if (glob->imsghook)
  528.     {
  529.         SetDrawerAndFileFields (glob);
  530.         CallHookPkt (glob->imsghook, glob->req, imsg);
  531.         ResetDrawerAndFileFields (glob);
  532.     }
  533.     ReplyMsg ((struct Message *)imsg);
  534.     }
  535.     
  536.     return (NULL);
  537. }
  538.  
  539. /****************************************************************************************/
  540.  
  541. void REGARGS SetDrawerAndFileFields (GlobData *glob)
  542. {
  543.     if (REQTYPE(glob->req) == RT_FILEREQ)
  544.     {
  545.     glob->tempdir = glob->freq->Dir;
  546.     glob->freq->Dir = glob->freq->dirname;
  547.     if (!(glob->flags & FREQF_NOFILES))
  548.     {
  549.         strcpy (glob->tempfname, glob->freq->filename);
  550.         strcpy (glob->freq->filename, ((struct StringInfo *)glob->filegad->SpecialInfo)->Buffer);
  551.     }
  552.     }
  553. }
  554.  
  555. /****************************************************************************************/
  556.  
  557. void REGARGS ResetDrawerAndFileFields (GlobData *glob)
  558. {
  559.     if (REQTYPE(glob->req) == RT_FILEREQ)
  560.     {
  561.     glob->freq->Dir = glob->tempdir;
  562.     if (!(glob->flags & FREQF_NOFILES))
  563.         strcpy (glob->freq->filename, glob->tempfname);
  564.     }
  565. }
  566.  
  567. /****************************************************************************************/
  568.  
  569. #ifdef _AROS
  570. AROS_UFH3(void, IntuiMsgFunc,
  571.     AROS_UFHA(struct Hook *, hook, A0),
  572.     AROS_UFHA(APTR, req, A2),
  573.     AROS_UFHA(struct IntuiMessage *, imsg, A1))
  574. #else
  575. void ASM SAVEDS IntuiMsgFunc (
  576.     REGPARAM(a0, struct Hook *, hook),
  577.     REGPARAM(a2, APTR, req),
  578.     REGPARAM(a1, struct IntuiMessage *,imsg))
  579. #endif
  580. {
  581.     GlobData *glob = (GlobData *)hook->h_Data;
  582.  
  583.     if (imsg->IDCMPWindow == glob->reqwin)
  584.     {
  585.     if (imsg->Class == IDCMP_REFRESHWINDOW) RenderReqWindow (glob, TRUE, FALSE);
  586.     }
  587.     else if (glob->imsghook)
  588.     {
  589.     SetDrawerAndFileFields (glob);
  590.     CallHookPkt (glob->imsghook, glob->req, imsg);
  591.     ResetDrawerAndFileFields (glob);
  592.     }
  593. }
  594.  
  595. /****************************************************************************************/
  596.  
  597. /* Improve this function to handle:
  598.  * 1) Volume lists in the file requester
  599.  * 2) The font requester
  600.  */
  601. int REGARGS FindEntryPos (GlobData *glob, char *name, int entry_id)
  602. {
  603.     struct ReqEntry *entry, *entry2;
  604.     int i, val;
  605.  
  606.     if (!glob->buff->firstname) return (0);
  607.     i = 0;
  608.     if (*name && (entry = FindEntry (glob->buff, name, -1, entry_id, NULL, FIND_VOLUMENAME)))
  609.     {
  610.     entry2 = (struct ReqEntry *)glob->buff->firstname->re_Next;
  611.     while (entry2 != (struct ReqEntry *)entry->re_Next)
  612.     {
  613.         if (!(entry2->re_Flags & ENTRYF_HIDDEN)) i++;
  614.         entry2 = (struct ReqEntry *)entry2->re_Next;
  615.     }
  616.     }
  617.     
  618.     glob->buff->gotopos = i;
  619.     val = glob->buff->currentnum - glob->numentries;
  620.     
  621.     if (glob->buff->gotopos > val) glob->buff->gotopos = val;
  622.     if (glob->buff->gotopos < 0) glob->buff->gotopos = 0;
  623.     
  624.     if (glob->buff->pos != glob->buff->gotopos)
  625.     {
  626.     glob->buff->pos = glob->buff->gotopos;
  627.     AdjustScroller (glob);
  628.     UpdateDisplayList (glob);
  629.     PrintFiles (glob);
  630.     }
  631.     
  632.     if (i >= glob->buff->currentnum) i = (glob->buff->currentnum - 1);
  633.     
  634.     return (i);
  635. }
  636.  
  637. /****************************************************************************************/
  638.  
  639. void REGARGS DeselectFiles (GlobData *glob, int clicked, int dirsonly)
  640. {
  641.     int i;
  642.  
  643.     for (i = 0; i < glob->numentries; i++)
  644.     {
  645.     if (i >= glob->buff->currentnum) break;
  646.     
  647.     if (i != clicked)
  648.     {
  649.         if (dirsonly && (glob->displaylist[i]->re_Type == glob->file_id))
  650.         continue;
  651.         
  652.         if (glob->displaylist[i]->re_Flags & ENTRYF_SELECTED)
  653.         {
  654.         glob->numselected--;
  655.         glob->displaylist[i]->re_Flags &= ~ENTRYF_SELECTED;
  656.         PrintEntry (glob, i);
  657.         }
  658.     }
  659.     }
  660. }
  661.  
  662. /****************************************************************************************/
  663.  
  664. int REGARGS
  665. ClickDown( GlobData *glob, int clicked, struct IntuiMessage *reqmsg, int qual )
  666. {
  667.     struct BufferData    *buff;
  668.     struct ReqEntry        *entry;
  669.     char    *str, *str2, tempstr[108];
  670.     int    ctype, val;
  671.  
  672.     buff = glob->buff;
  673.  
  674.     if( clicked >= buff->currentnum )
  675.     {
  676.         return( FALSE );
  677.     }
  678.  
  679.     glob->clicked = clicked;
  680.     entry = glob->displaylist[ clicked ];
  681.  
  682.     if( entry->re_Flags & ENTRYF_GHOSTED )
  683.     {
  684.         entry->re_Flags &= ~ENTRYF_SELECTED;
  685.         glob->downgadget = 0;
  686.         return( FALSE );
  687.     }
  688.  
  689.     str = entry->re_Name;
  690.     str2 = "";
  691.     val = !( ( glob->flags & FREQF_MULTISELECT ) && ( qual & IEQUALIFIER_SHIFT ) );
  692.     ctype = entry->re_Type;
  693.  
  694.     if( ctype == glob->file_id )
  695.     {
  696.     if( !( entry->re_Flags & ENTRYF_SELECTED ) || val )
  697.     {
  698.         str2 = str;
  699.     }
  700.  
  701.     goto filefont;
  702.     }
  703.     else if( ctype == glob->directory_id )
  704.     {
  705.     if( !reqmsg )
  706.     {
  707.         strcpy( tempstr, str );
  708.         StrCat( tempstr, "/" );
  709.         str2 = tempstr;
  710.     }
  711.     else if( !( glob->flags & FREQF_SELECTDIRS ) )
  712.     {
  713.         goto nodirselect;
  714.     }
  715.  
  716. filefont:
  717.     my_SetStringGadget( glob->reqwin, glob->filegad, str2 );
  718.  
  719.     if( !( glob->flags & FREQF_SELECTDIRS ) )
  720.     {
  721.         DeselectFiles( glob, clicked, TRUE );
  722.         CountAllDeselect( glob, TRUE );
  723.     }
  724.  
  725.     if( val )
  726.     {
  727.         DeselectFiles( glob, clicked, FALSE );
  728.         CountAllDeselect (glob, FALSE);
  729.     }
  730.  
  731.     if( reqmsg )
  732.     {
  733.         if( ( clicked == glob->lastclicked ) &&
  734.             DoubleClick( glob->sec, glob->mic, reqmsg->Seconds, reqmsg->Micros ) )
  735.         {
  736.         if( ctype == glob->directory_id )
  737.         {
  738.             AddPart( glob->freq->dirname, str, sizeof( glob->freq->dirname ) );
  739.             NewDir( glob );
  740.             return( FALSE );
  741.         }
  742.         else if( !( glob->flags & ( FREQF_SAVE | FREQF_NOFILES ) ) )
  743.         {
  744.             entry->re_Flags |= ENTRYF_SELECTED;
  745.             return( TRUE );
  746.         }
  747.         }
  748.     }
  749.  
  750.     if( glob->flags & FREQF_MULTISELECT )
  751.     {
  752.         if( entry->re_Flags & ENTRYF_SELECTED )
  753.         {
  754.         glob->numselected--;
  755.         }
  756.         else
  757.         {
  758.         glob->numselected++;
  759.         }
  760.  
  761.         UpdateNumSelGad( glob );
  762.     }
  763.  
  764.     entry->re_Flags ^= ENTRYF_SELECTED;
  765.  
  766.     if( ( entry->re_Flags & ENTRYF_SELECTED ) && glob->buff->sorted )
  767.     {
  768.         glob->selectedpos = ( glob->buff->pos + clicked );
  769.     }
  770.  
  771.     PrintEntry( glob, clicked );
  772.     glob->downgadget = 0;
  773.  
  774.     if( reqmsg )
  775.     {
  776.         glob->sec = reqmsg->Seconds;
  777.         glob->mic = reqmsg->Micros;
  778.         glob->lastclicked = clicked;
  779.     }
  780.     }
  781.     else
  782.     {
  783.     if( !reqmsg )
  784.     {
  785.         str2 = str;
  786.  
  787.         if( ctype == VOLUME )
  788.         {
  789.         while( *str2++ != ' ' )
  790.         {
  791.         }
  792.  
  793.         while( *str2 == ' ' )
  794.         {
  795.             str2++;
  796.         }
  797.         }
  798.  
  799.         goto filefont;
  800.  
  801.     }
  802.  
  803. nodirselect:
  804.     CompClicked( glob );
  805.     }
  806.  
  807.     return( FALSE );
  808. }
  809.  
  810. /****************************************************************************************/
  811.  
  812. /*****************
  813. * Requester exit *
  814. *****************/
  815.  
  816. ULONG REGARGS LeaveReq (GlobData *glob, char *filename)
  817. {
  818.     struct rtFileList *selfile = (APTR)TRUE;
  819.     int flags = glob->flags, nodir = glob->nodir;
  820.     int allowempty = glob->allowempty;
  821.  
  822.     if (glob->filestr) strcpy (filename, glob->filestr);
  823.     
  824.     if (glob->reqtype == RT_FILEREQ)
  825.     {
  826.     if (!(flags & FREQF_MULTISELECT))
  827.     {
  828.         FreeAllCheckBuffer (glob);
  829.         /* can't use glob here anymore because it is freed! */
  830.         if (flags & FREQF_NOFILES) return ((ULONG)!nodir);
  831.         if (!nodir && (filename[0] || allowempty)) return (TRUE);
  832.         return (NULL);
  833.     }
  834.     
  835.     if (!nodir)
  836.     {
  837.         if (!(glob->flags & FREQF_SELECTDIRS)) CountAllDeselect (glob, TRUE);
  838.         selfile = AllocSelectedFiles (glob);
  839.     }
  840.     else selfile = NULL;
  841.     }
  842.     else if (glob->reqtype == RT_FONTREQ)
  843.     {
  844.     glob->fontreq->Attr.ta_Style &= ~(FSF_ITALIC|FSF_BOLD|FSF_UNDERLINED);
  845.     glob->fontreq->Attr.ta_Style |= glob->fontstyle;
  846.     selfile = (APTR)(filename[0] != 0);
  847.     }
  848.     else
  849.     {
  850.     if (glob->modeid == INVALID_ID) selfile = FALSE;
  851.     else
  852.     {
  853.         glob->scrmodereq->DisplayID = glob->modeid;
  854.         if (glob->modeid & HAM ) glob->depth = (glob->depth == 7 ? 6 : 8 );
  855.         glob->scrmodereq->DisplayDepth = glob->depth;
  856.         glob->scrmodereq->DisplayWidth = glob->width;
  857.         glob->scrmodereq->DisplayHeight = glob->height;
  858.         glob->scrmodereq->OverscanType = glob->overscantype;
  859.         glob->scrmodereq->AutoScroll = glob->autoscroll;
  860.     }
  861.     }
  862.     
  863.     FreeAllCheckBuffer (glob);
  864.     
  865.     return ((ULONG)selfile);
  866. }
  867.  
  868. /****************************************************************************************/
  869.  
  870. static void REGARGS CloseWinFreeRest (GlobData *glob)
  871. {
  872.     StopTimer (glob);
  873.  
  874.     if (glob->reqtype == RT_FILEREQ)
  875.     CloseDevice ((struct IORequest *)&glob->timereq);
  876.     FreeVpCM (glob->vp, glob->colormap, !(glob->flags & FREQF_LEAVEPALETTE));
  877.  
  878.     if (glob->newreqwin.Type == PUBLICSCREEN) UnlockPubScreen (NULL, glob->scr);
  879.     DoScreenToFront (glob->frontscr, glob->noscreenpop, FALSE);
  880.  
  881.     if (glob->reqwin)
  882.     {
  883.     *glob->winaddr = glob->oldwinptr;
  884.     DoLockWindow (glob->prwin, glob->lockwindow, glob->winlock, FALSE);
  885.     DoWaitPointer (glob->prwin, glob->waitpointer, FALSE);
  886.     
  887.     if (glob->appwindow) RemoveAppWindow (glob->appwindow);
  888.     
  889.     DeleteMsgPort (glob->appwinport);
  890.     CloseLibrary (WorkbenchBase);
  891.     DoCloseWindow (glob->reqwin, glob->shareidcmp);
  892.     }
  893.     
  894.     my_FreeGadgets (glob->buttoninfo.glist);
  895.     my_FreeLabelImages (&glob->labelimages);
  896.     FreeVisualInfo (glob->visinfo);
  897.     
  898.     if (glob->drinfo) FreeScreenDrawInfo (glob->scr, glob->drinfo);
  899.     if (glob->reqfont) CloseFont (glob->reqfont);
  900.     
  901.     CloseLibrary (glob->diskfontbase);
  902.     FreeVec (glob);
  903. }
  904.  
  905. /****************************************************************************************/
  906.  
  907. void REGARGS FreeAllCheckBuffer (GlobData *glob)
  908. {
  909.     if (glob->lock || (glob->disks && !glob->volumerequest)
  910.            || (glob->flags & FREQF_NOBUFFER))
  911.     FreeAll (glob);
  912.     else CloseWinFreeRest (glob);
  913. }
  914.  
  915. /****************************************************************************************/
  916.  
  917. void REGARGS FreeAll (GlobData *glob)
  918. {
  919.     FreeReqBuffer (glob->req);
  920.     UnLockReqLock (glob);
  921.     CloseWinFreeRest (glob);
  922. }
  923.  
  924. /****************************************************************************************/
  925.  
  926. struct rtFileList *REGARGS AllocSelectedFiles (GlobData *glob)
  927. {
  928.     struct rtFileList *ptr, **last, *selfile;
  929.     struct ReqEntry *entry;
  930.     int len, isfile, foundstr = FALSE;
  931.     /* We do some checks agains the file gadget if available,
  932.      * or the path gadget, if there is no file gadget, and we thus
  933.      * are a volume requester or something similar
  934.      */
  935.     char *str, *gadstr = glob->filegad ? glob->filestr : glob->patgadstr;
  936.  
  937.     selfile = NULL; last = &selfile;
  938.     for (entry = (struct ReqEntry *)glob->firstentry->re_Next;;
  939.      entry = (struct ReqEntry *)entry->re_Next)
  940.    {
  941.     if (!entry)
  942.     {
  943.         /* We build the filelist, now we check if the filename in
  944.             the gadget is among the ones in the list */
  945.         str = gadstr;
  946.         if (foundstr || !*str) break;
  947.         /* The filename in the gadget is not is the list!
  948.             We will discard the list and only return the filename in the
  949.             gadget!  This is the most intuitive behaviour! */
  950.         rtFreeFileList (selfile);
  951.         selfile = NULL; last = &selfile;
  952.         isfile = TRUE;
  953.     }
  954.     else
  955.     {
  956.         if (!(entry->re_Flags & ENTRYF_SELECTED)) continue;
  957.         str = entry->re_Name;
  958.         isfile = entry->re_Type == glob->file_id;
  959.         if (!Stricmp (str, gadstr)) foundstr = TRUE;
  960.     }
  961.     
  962.     len = strlen (str);
  963.     
  964.     if (!(ptr = (struct rtFileList *)AllocVec(sizeof (struct rtFileList) + len + 1,
  965.                           MEMF_PUBLIC|MEMF_CLEAR)))
  966.     {
  967.         rtFreeFileList (selfile);
  968.         return (NULL);
  969.     }
  970.     
  971.     ptr->StrLen = isfile ? len : -1;
  972.     ptr->Name = (char *)(4 + (ULONG)&ptr->Name);
  973.     strcpy (ptr->Name, str);
  974.     *last = ptr;
  975.     last = &ptr->Next;
  976.     
  977.     if (!entry) break;
  978.     }
  979.     
  980.     return (selfile);
  981. }
  982.  
  983. /****************************************************************************************/
  984.